//
// CSampleAdmin.cpp
//
/**
 ** Copyright (C) 2005 EnjoyView Inc., all rights reserved.
 **           Your View, Our Passion. Just Enjoy It!
 **
 **            http://spaces.msn.com/members/jemylu
 **
 **/

/*************************************************************************/

#include "stdafx.h"
#include "CWMSample.h"
#include "CSampleAdmin.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
CSampleAdmin::CSampleAdmin()
{
	mSampleCount = 0;
}

CSampleAdmin::~CSampleAdmin()
{
	Uninit();
}

HRESULT CSampleAdmin::Init(int inCount, DWORD inBufferSize)
{
	mSampleCount = inCount;

	// Allocate samples and add them to the list
	for (int i = 0; i < inCount; i++)
	{
		CWMSample * pSample = new CWMSample(this);
		pSample->VerifyBufferSize(inBufferSize);
		mSampleList.AddTail(pSample);
	}

	return S_OK;
}

HRESULT CSampleAdmin::Uninit(void)
{
	// Check if all samples are back to the list
	ASSERT(mSampleCount == mSampleList.GetCount());

	// Remove samples from the list and release memory
	POSITION pos = mSampleList.GetHeadPosition();
	while (pos)
	{
		CWMSample * pSample = (CWMSample *) mSampleList.GetNext(pos);
		if (pSample)
		{
			delete pSample;
			pSample = NULL;
		}
	}
	mSampleList.RemoveAll();
	mSampleCount = 0;

	return S_OK;
}

// Get a free sample from the list
HRESULT CSampleAdmin::GetEmptySample(DWORD inRequiredSize, INSSBuffer ** outBuffer)
{
	while (mSampleList.IsEmpty())
	{
		Sleep(100);
	}

#ifdef _DEBUG
	TRACE("Free: %d\n", mSampleList.GetCount());
#endif // _DEBUG

	// Get a free sample from the head of the list
	CWMSample * pSample = (CWMSample *) mSampleList.RemoveHead();
	if (pSample)
	{
		// Verify the buffer size
		pSample->VerifyBufferSize(inRequiredSize);
		pSample->AddRef();  // !!!
		*outBuffer = (INSSBuffer *) pSample;
		TRACE("A free sample is out for using...\n");
	}
	return S_OK;
}

HRESULT CSampleAdmin::Reuse(CWMSample * inSample)
{
	// Add the sample to the list again for later use
	mSampleList.AddTail(inSample);
	TRACE("The sample comes back to the list.\n");
	return S_OK;
}